#pragma once

#include <cstdint>
#include <list>
#include <vector>

#include "net_common.h"
#include "game_manager.h"

/* 单线程游戏匹配，后续引入one loop per thread 模型后，需要考虑使用多线程实现 */
class matching {
public:
    enum matching_result {
        MATCHING_SUCCESS = 0,
        MATCHING_WATING_FOR_PLAYER = 1,         /* 匹配池中的玩家数量不足以创建一场对局时返回 */
        MATCHING_USER_ALREADY_IN_MATCHING = 2,
        MATCHING_USER_NOT_IN_MATCHING = 3,
        MATCHING_OTHER_FAILED = 4,
    };

    matching(const matching &) = delete;
    matching &operator=(const matching &) = delete;

    static matching &get_instance()
    {
        static matching instance_;
        return instance_;
    }

    /**
     * @brief 玩家加入匹配
     * @param uid 玩家id
     * @param user_list 匹配成功的玩家列表
     */
    matching_result player_join_in(uint32_t uid, std::vector<uint32_t> &user_list)
    {
        int ret = NET_EC_OK;
        auto find_ret = std::find(pending_players_.begin(), pending_players_.end(), uid);
        if (find_ret != pending_players_.end()) {
            /* 玩家已经在匹配池中 */
            std::cout << "player already in matching" << std::endl;
            return MATCHING_USER_ALREADY_IN_MATCHING;
        }
        pending_players_.push_back(uid);
        if (pending_players_.size() >= target_player_num_) {
            /* 匹配成功，开始游戏 */
            user_list.clear();
            for (int i = 0; i < target_player_num_; ++i) {
                user_list.push_back(pending_players_.front());
                pending_players_.pop_front();
            }
            return MATCHING_SUCCESS;
        }

        std::cout << "waiting for player" << std::endl;
        return MATCHING_WATING_FOR_PLAYER;
    }


    int player_leave(uint32_t uid)
    {
        int ret = NET_EC_OK;
        for (auto it = pending_players_.begin(); it != pending_players_.end(); ++it) {
            if (*it == uid) {
                pending_players_.erase(it);
                return NET_EC_OK; 
            }
        }
        
        std::cout << "player not in matching" << std::endl;
        return MATCHING_USER_NOT_IN_MATCHING;
    }

private:
    matching() = default;
    ~matching() = default;

    int target_player_num_ = 2;         /* 一场对局由几个玩家组成 */
    std::list<int> pending_players_;    /* 等待匹配的玩家列表 */

    static matching *instance_;
};

